<!--
 * @Description: 流程审批主体、发起流程和流程审批的几个主要组件
 * @Author: wangwangwang
 * @Date: 2020-11-26 13:50:09
 * @LastEditors: wangwangwang
 * @LastEditTime: 2021-09-08 15:18:40
-->
<template>
  <section v-loading="loading">
    <FlowsNodeList v-if="readOnly" :tableData="approveTableData" />
    <approvalModal :approvalVisible='approvalVisible' :approvalNode='approvalNode' @sendApprovePerson="sendApprovePerson" @handleModal="handleModal" />
    <!-- 流程审批操作 -->
    <Flowbackup :visible="backVisible" :tableData="backTableData" @closeModel="backVisible=false" @hanldeSure='hanldeSure' />
    <HandleNode :visible='nodeVisible' :sendTable="approveTableData" @hanldeClose="nodeVisible=false" @hanldeSure="hanldeSure2" />
    <OperationModal :showSendVisible="showSendVisible" @handleSure="handleSend" @handleCancel="handleCancel" />
    <FlowMap :visible='mapVisible' :nodeDataSource="allNode" @closeModel="mapVisible=false" />
    <personModel :title="handleTitle" :visible='visible' @closeModel='visible=false' @getPerson='getPerson' />
  </section>
</template>
<script>
import FlowsNodeList from '@/components/WorkFlow/flowsNodeList';
import approvalModal from '@/components/WorkFlow/approvalModal';
import OperationModal from '@/components/WorkFlow/OperationModal';
import FlowMap from '@/components/WorkFlow/flowMap';
import personModel from '@/components/ChoisePerson/personModel';
import Flowbackup from '@/components/WorkFlow/flowbackup';
import HandleNode from '@/components/WorkFlow/handleNode';
import { taskCollectByUser } from '@/api/task/taskType';
import { getNodeList, submitApproval, submitTask, saveWorkFlow, previewProcess, getFlowsCode, addApprover, assignmentApprover, backPrefixNode, cancelTask, cancelTask2 } from '@/api/task/flows';
import addTab from "@/common/addTab.js";
import { getUserId } from '@/utils/auth.js';
export default {
  props: ["code", 'title', 'showSendVisible'],
  components: {
    approvalModal,
    OperationModal,
    FlowsNodeList,
    FlowMap,
    personModel,
    Flowbackup,
    HandleNode,
  },
  data() {
    return {
      loading: false,
      approvalVisible: false,
      mapVisible: false,
      visible: false,
      backVisible: false,
      nodeVisible: false,
      approveTableData: [],
      approvalNode: [],
      flowsBaseInfo: {},
      readOnly: false,
      sendPerson: '',
      dataSource: [],
      processManagerId: '',
      billCode: '',
      formData: {},
      allNode: [],
      backTableData: [],
      handleTitle: '',
      handleType: '',
      subordinateSystem: '',
      limiSend: false,
    }
  },
  methods: {
    initBaseData(code) {
      // 获取流程编码
      getFlowsCode({ code }).then(res => {
        if (res.code === 1001) {
          this.$emit('sendCode', res.data.code);
          this.billCode = res.data.code;
          this.processManagerId = res.data.processManagerId;
          this.subordinateSystem = res.data.systemName;
        }
      })
    },
    handleModal(type) {
      if (type === 1) { // 关闭弹窗
        this.approvalVisible = false;
      } else { // 提交流程
        this.handleSure();
      }
    },
    handleSure() {
      const { query } = this.$route;
      const nodeList = this.approvalNode.map((item) => {
        if (item.personList) {
          const newArry = item.personList.map((items) => {
            return {
              organization: '',
              station: '',
              userId: items.id,
              userName: items.name,
            }
          })
          return {
            ...item,
            userSet: newArry
          }
        } else {
          return item
        }
      });
      for (let i = 0; i < nodeList.length; i += 1) {
        if (!nodeList[i] ?.userSet ?.length) {
          this.$message({
            type: 'warning',
            message: `请选择节点序号为${i}的审批人`,
          })
          return
        }
      }
      const params = {
        nodeList,
        processManagerId: this.processManagerId || query.processManagerId, // 待发任务时数据从连接上获取,
        formType: '2',
        processTaskId: this.processTaskId,
      }
      if (this.limiSend) {
        return
      }
      this.limiSend = true
      submitTask(params).then(res => {
        this.limiSend = false
        if (res.code === 1001) {
          this.$message({
            type: 'success',
            message: '流程提交成功！！！'
          });
          this.$emit('handleFinish', 1)
          this.approvalVisible = false;
          this.$emit('submitData')
          addTab.$emit("remove", this.$route.name);
        }
      });
    },
    handleSend(formData) {
      this.formData = formData;
      if (formData.approvalStatus === '3') {
        this.$emit('resetFlowState', 1);
      }
      this.$emit('handleBusiness', formData);
    },
    /**
     * @Description: 流程接收业务数据  进行操作
     * @Param: 
     * @Author: wangwangwang
     */
    handleToFlow(data) {
      const newData = this.approveTableData.find((item) => item.approvalStatus === 1);
      if (!newData || !newData.processInstanceNodeId) {
        this.$message.warning('未找到当前审批节点');
        return
      }
      // 保障节点ID是字符串，而不是数组
      let nodeId = newData.processInstanceNodeId
      if (typeof nodeId === 'object') {
        nodeId = nodeId[0]
      }
      const params = {
        approvalOptions: this.formData.approvalOptions,
        approvalStatus: this.formData.approvalStatus,
        processInstanceId: newData.processInstanceId,
        processInstanceNodeId: Array.isArray(newData.processInstanceNodeId) ? newData.processInstanceNodeId[0] : newData.processInstanceNodeId,
        callbackData: JSON.stringify(data),
      }
      submitApproval(params).then(res => {
        if (res.code === 1001) {
          this.$message.success('提交成功');
					/**
					 * @Description: 如果是最后一个就调授权的接口
					 * @Param: 
					 * @Author: wangwangwang
					 */
          if (res.data ?.processResult === 'process_success') {
            this.$emit('handleFinish', 2, this.formData.approvalStatus)
          }
          addTab.$emit("remove", this.$route.name);
        }
      })
      console.log(101, params, newData.processInstanceNodeId)
    },
    /**
     * @Description: 父组件传值过来保存数据
     * @Param: 
     * @Author: wangwangwang
     */
    saveFlows(type, data, flowsType) {
      if (flowsType * 1 === 10) { // 强制编辑
        this.editTask(data);
      } else if (type === 1) { // 保存
        this.saveTask(data, flowsType);
      } else if (type === 2) { // 提交
        this.sendTask(data, flowsType);
      } else if (type === 3) { // 撤销
        this.handleBackEnd(data);
      } else if (type === 4) { // 抄送
        this.visible = true;
        this.handleType = 1;
        this.handleTitle = '选择抄送人员'
      } else if (type === 5) { // 交办
        this.visible = true;
        this.handleType = 3;
        this.handleTitle = '选择交办人员'
      } else if (type === 6) { // 回退
        this.backTableData = this.approveTableData.filter(item => item.approvalStatus === 2);
        this.backVisible = true;
      } else if (type === 7) { // 协审
        this.visible = true;
        this.handleType = 2;
        this.handleTitle = '选择协审人员'
      } else if (type === 8) { // 加减签
        this.nodeVisible = true;
      } else if (type === 9) { // 流程图
        this.showNodeImage();
      } else if (type === 10) { // 收藏任务
        this.handleCollection();
      }
    },
    editTask (data) {
      const { query } = this.$route;
      if (!this.title) {
        this.$message.warning('流程标题为空，请输入标题');
        return
      }
      const params = {
        taskType: 1,
        formType: 2,
        taskStatus: 3,
        subordinateSystem: this.subordinateSystem,
        processManagerId: this.processManagerId || query.processManagerId, // 待发任务时数据从连接上获取
        receiptNumber: this.billCode || query.receiptNumber, // 待发任务时数据从连接上获取
        taskName: this.title,
        ...data,
      }
      saveWorkFlow(params).then(res => {
        if (res.code === 1001) {
          this.$message.success('强制编辑成功');
          addTab.$emit("remove", this.$route.name);
        }
      });
    },
    saveTask(data, saveTask) {
      const { query } = this.$route;
      if (!this.title) {
        this.$message.warning('流程标题为空，请输入标题');
        return
      }
      if (!(this.processManagerId || query.processManagerId)) {
        this.$message.warning('未获取到流程信息，请关闭菜单后重新发起!!!');
        return
      }
      const params = {
        taskType: saveTask?2:1,
        formType: 2,
        subordinateSystem: this.subordinateSystem,
        taskStatus: saveTask?'':1,
        processManagerId: this.processManagerId || query.processManagerId, // 待发任务时数据从连接上获取
        receiptNumber: this.billCode || query.receiptNumber, // 待发任务时数据从连接上获取
        taskName: this.title,
        ...data,
      }
      if (!(this.billCode || query.receiptNumber)) {
        this.$message.warning('单据编号为空，请稍等或刷新');
        return
      }
      saveWorkFlow(params).then(res => {
        if (res.code === 1001) {
          this.processTaskId = res.data;
          this.$store.dispatch("setProcessTaskId", res.data);
          if (!saveTask) {
            this.$message.success('保存成功');
          }
        }
      });
    },
    sendTask(data,saveTask) {
      const { query } = this.$route;
      if (!this.title) {
        this.$message.warning('流程标题为空，请输入标题');
        return
      }
      if (!(this.billCode || query.receiptNumber)) {
        this.$message.warning('单据编号为空，请稍等或刷新');
        return
      }
      const params = {
        taskType: saveTask?2:1,
        formType: 2,
        taskStatus: 1,
        processManagerId: this.processManagerId || query.processManagerId, // 待发任务时数据从连接上获取
        receiptNumber: this.billCode || query.receiptNumber, // 待发任务时数据从连接上获取
        taskName: this.title,
        ...data,
      }
      saveWorkFlow(params).then(res => {
        if (res.code === 1001) {
          this.processTaskId = res.data;
          this.$store.dispatch("setProcessTaskId", res.data);
          this.showApprovePerson();
        }
      });
    },
    showNodeImage() {
      this.mapVisible = true;
    },
    handleCollection() {
      const { query } = this.$route;
      const params = [{ receiptNumber: this.billCode || query.receiptNumber }]
      taskCollectByUser(params).then(res => {
        if (res.code === 1001) {
          this.$message.success('收藏成功');
        }
      })
    },
    showApprovePerson() {
      const { query } = this.$route;
      const params = {
        processManagerId: this.processManagerId || query.processManagerId, // 待发任务时数据从连接上获取
      }
      previewProcess(params).then(res => {
        if (res.code === 1001) {
          this.approvalNode = res.data.nodeList.map((item) => {
            if (item ?.userSet ?.length) {
              return {
                ...item,
                showName: (item.userSet.map((item) => item.userName)).join(',', ),
              }
            } else {
              return item
            }
          });
          this.approvalVisible = true;
        }
      })
    },
    sendApprovePerson(choisePerson, index) {
      const data = {
        showName: (choisePerson.map((item) => item.name)).join(','),
      }
      const newArry = this.approvalNode.map((item, idx) => {
        if (index === idx) {
          return {
            ...item,
            ...data,
            personList: choisePerson,
          }
        } else {
          return item
        }
      })
      this.approvalNode = newArry;
    },
    initBusiness() {
      const { query } = this.$route;
      this.dataContent = JSON.parse(query.dataContent);
      this.readOnly = true;
      /**
			* @Description: 获取流程节点信息
			* @Param: 
			* @Author: wangwangwang
      */
      const params = {
        processManagerId: query.processManagerId,
        processTaskId: query.processTaskId,
        processVersionId: query.processVersionId,
        receiptNumber: query.receiptNumber,
      }
      getNodeList(params).then(res => {
        if (res.code === 1001) {
          this.allNode = JSON.parse(JSON.stringify(res.data));
          const newData = [];
          res.data.forEach(item => {
            // item.instanceLogsList.forEach(items => {
            //   const data = {
            //     nodeName: item.nodeName,
            //     userName: items.userName,
            //     userId: items.userId,
            //     multiApprovalType: items.multiApprovalType,
            //     approvalOptions: items.approvalOptions,
            //     handlerTime: items.handlerTime,
            //     id: item.id,
            //     approvalStatus: item.approvalStatus,
            //     processInstanceId: item.processInstanceId,
            //     processInstanceNodeId: items.processInstanceNodeId,
            //   }
            //   newData.push(data);
            // })
            const data = {
              nodeName: item.nodeName,
              userName: item.instanceLogsList.map(sItem=>sItem.userName),
              userId: item.instanceLogsList.map(sItem=>sItem.userId),
              multiApprovalType: item.multiApprovalType,
              approvalOptions: item.instanceLogsList.map(sItem=>sItem.approvalOptions),
              handlerTime: item.instanceLogsList.map(sItem=>sItem.handlerTime),
              id: item.id,
              approvalStatus: item.approvalStatus,
              processInstanceId: item.processInstanceId,
              processInstanceNodeId: item.instanceLogsList.map(sItem=>sItem.processInstanceNodeId),
            }
            newData.push(data);
          });
          const firstPerson = res.data[0].instanceLogsList[0].userId;
          this.$store.dispatch("user/setFlowsId", firstPerson);
          this.approveTableData = newData;
          for (let i = 0; i < res.data.length; i += 1) {
            if (res.data[i].approvalStatus === 1) {
              if (res.data[i].formColumnData) {
                this.$emit('setElement', JSON.parse(res.data[i].formColumnData));
                return
              }
            }
            if (query.taskType*1===5) {
              for (let j = 0; j < res.data[i]?.instanceLogsList.length; j+=1) {
                if (getUserId() === res.data[i].instanceLogsList[j].userId && res.data[i].formColumnData) {
                  this.$emit('setElement', JSON.parse(res.data[i].formColumnData));
                }
              }
            }
          }
        }
      });
    },
    handleCancel() {
      this.$emit('handleCancel');
    },
    hanldeSure(data) {
      const newData = this.approveTableData.find((item) => item.approvalStatus === 1);
      if (!newData.processInstanceNodeId) {
        this.$message.warning('未找到当前审批节点');
        return
      }
      const params = {
        sourceNodeId: Array.isArray(newData.processInstanceNodeId) ? newData.processInstanceNodeId[0] : newData.processInstanceNodeId,
        targetNodeId: data.id,
      }
      backPrefixNode(params).then(res => {
        if (res.code === 1001) {
          this.$message.success('回退成功');
          addTab.$emit("remove", this.$route.name);
        }
      })
    },
    /**
     * @Description: 加减签
     * @Param: 通过对比进行判断
     * @Author: wangwangwang
     * @param {*} data
     */
    hanldeSure2(data) {
      const allHasData = this.approveTableData.filter(item => data.some(items => (items.userId === item.userId && items.processInstanceId === item.processInstanceId)));
      const deleteData = this.approveTableData.filter(item => !allHasData.some(items => (items.userId === item.userId && items.processInstanceId === item.processInstanceId)));
      const addData = data.filter(item => !allHasData.some(items => (items.userId === item.userId && items.processInstanceId === item.processInstanceId)));
      const params = addData.concat(deleteData.map(item => ({ ...item, status: 0 })));
      addApprover(params).then(res => {
        if (res.code === 1001) {
          this.$message.success('操作成功！！！');
          this.nodeVisible = false;
        }
      })
    },
    getPerson(data) {
      const newData = this.approveTableData.find((item) => item.approvalStatus === 1);
      if (!newData.processInstanceNodeId) {
        this.$message.warning('未找到当前审批节点');
        return
      }
      if (this.handleType === 1) { // 抄送
        const params = data.map(item => ({ userId: item.id, userType: 3, userName: item.name, processInstanceId: newData.processInstanceId, processInstanceNodeId: newData.processInstanceNodeId }))
        addApprover(params).then(res => {
          if (res.code === 1001) {
            this.$message.success('抄送成功！！！');
            this.visible = false;
          }
        })
      }
      if (this.handleType === 2) { // 协审
        const params = data.map(item => ({ userId: item.id, userType: 2, userName: item.name, processInstanceId: newData.processInstanceId, processInstanceNodeId: newData.processInstanceNodeId }))
        addApprover(params).then(res => {
          if (res.code === 1001) {
            this.$message.success('添加协审成功！！！');
            this.visible = false;
          }
        })
      }
      if (this.handleType === 3) { // 交办
        if (data.length > 1) {
          this.$message.warning('交办人员不能大于1位');
          return
        }
        let nodeId = newData.processInstanceNodeId
        if (typeof newData.processInstanceNodeId === 'object') {
          nodeId = newData.processInstanceNodeId[0]
        }
        const params = {
          processInstanceNodeId: nodeId,
          userIds: data[0].id,
          userName: data[0].name,
        }
        assignmentApprover(params).then(res => {
          if (res.code === 1001) {
            this.visible = false;
            this.$message.success('交办成功！！！');
            setTimeout(() => {
              addTab.$emit("remove", this.$route.name);
            }, 1000)
          }
        })
      }
    },
    handleBackEnd(data) {
      const { query } = this.$route;
      this.$confirm('确定撤销此流程?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        cancelButtonClass: 'bottom_all_two',
        confirmButtonClass: 'bottom_all',
        type: 'warning'
      }).then(() => {
        const params = {
          taskId: query.processTaskId,
        }
        cancelTask(params).then(res => {
          if (res.code === 1001) {
            cancelTask2(data)
            this.$message.success('撤销成功', 1, () => {
              this.$emit('resetFlowState', 2);
              addTab.$emit("remove", this.$route.name);
            });
          }
        })
      }).catch(() => {
      });
    }
  },
  mounted() {
    /**
     * @Description: 流程审批用户回显流程相关数据、发起流程不调用此方法
     * @Param: 
     * @Author: wangwangwang
     */
    const { query } = this.$route;
    if (query.type * 1 === 2 && query.taskType * 1 !== 2) {
      this.initBusiness();
    }
    this.$store.dispatch("setProcessTaskId", '');
  }
}
</script>
<style scoped>
</style>
